/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ds_Queue;

/**
 *
 * @author hcc25_000
 */
public class MyCircularArrayQueue<T> implements MyQueueADT<T> {

    private static final int DEFAULT_CAPACITY = 6;
    private int front, rear, count;
    private T[] queue;

    public MyCircularArrayQueue(int initalCapacity) {
        front = rear = count = 0;
        queue = ((T[]) (new Object[initalCapacity]));
    }

    public MyCircularArrayQueue() {
        this(DEFAULT_CAPACITY);
    }

    public void enqueue(T element) {
        if (size() == queue.length) {
            expandCapacity();
        }

        queue[rear] = element;
        rear = (rear + 1) % queue.length;

        count++;
    }

    public T dequeue() {
        if (isEmpty()) {
            throw new MyEmptyCollectionException("queue");
        }

        T result = queue[front];
        queue[front] = null;
        front = (front + 1) % queue.length;
        count--;

        return result;
    }

    public T first() {
        if (isEmpty()) {
            throw new MyEmptyCollectionException("queue");
        }
        return queue[front];
    }

    public boolean isEmpty() {
        return count == 0;
    }

    public int size() {
        return count;
    }

    public void expandCapacity() {
        T[] larger = (T[]) (new Object[queue.length * 2]);
        for (int scan = 0; scan < count; scan++) {
            larger[scan] = queue[front];
            front = (front + 1) % queue.length;
        }
        front = 0;
        rear = count;
        queue = larger;
    }

    public void showInfo() {
        if (isEmpty()) {
            throw new MyEmptyCollectionException("queue");
        }
        int num1=front;
        int num2=0;
        while(num2<count){
            System.out.println(""+num1+" "+queue[num1]);
            num2++;
            num1=(num1+1)%queue.length;
        }
    }
}
